package model

import (
	"database/sql"
	"encoding/json"
	"time"
	"wxpay/pkg/util"

	"gorm.io/datatypes"
)

/*
DB Table Details
-------------------------------------


Table: profitshare
[ 0] id                                             INT8                 null: false  primary: true   isArray: false  auto: false  col: INT8            len: -1      default: []
[ 1] brand_id                                       VARCHAR(16)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 16      default: []
[ 2] mch_id                                         VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
[ 3] sub_mch_id                                     VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
[ 4] appid                                          VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
[ 5] wx_trans_id                                    VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
[ 6] out_order_no                                   VARCHAR(64)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 64      default: []
[ 7] receivers                                      JSONB                null: false  primary: false  isArray: false  auto: false  col: JSONB           len: -1      default: []
[ 8] status                                         VARCHAR(255)         null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 255     default: []
[ 9] wx_order_id                                    VARCHAR(64)          null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 64      default: []
[10] close_reason                                   VARCHAR(255)         null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 255     default: []
[11] finish_amount                                  INT8                 null: true   primary: false  isArray: false  auto: false  col: INT8            len: -1      default: []
[12] finish_description                             VARCHAR(80)          null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 80      default: []
[13] extra                                          JSONB                null: true   primary: false  isArray: false  auto: false  col: JSONB           len: -1      default: []
[14] create_time                                    TIMESTAMPTZ          null: false  primary: false  isArray: false  auto: false  col: TIMESTAMPTZ     len: -1      default: []
[15] update_time                                    TIMESTAMPTZ          null: false  primary: false  isArray: false  auto: false  col: TIMESTAMPTZ     len: -1      default: []


JSON Sample
-------------------------------------
{    "wx_trans_id": "SstfwpIFeNwYugdcydYyLKYLF",    "finish_description": "ITvPNayuabSPsJmORBGChxUFo",    "extra": "OqjpXhfBnoewNOnXoddnXXvfI",    "close_reason": "jItuLZqFVjllbAshfgoDXULYV",    "create_time": "2155-08-29T04:03:45.209561404+08:00",    "id": 55,    "brand_id": "BfdiDwhTBXHUMWOYRSWGgqpFI",    "out_order_no": "SILpBpChAiCnKypQKbxnAAxGo",    "status": "hjNLYUgpavicXMHcsjSVgWtUW",    "receivers": "MuTSjANCWjEUQnnnlfZDpYyJd",    "wx_order_id": "aUrVJbCcYWWdsgNGDxKTqqZsc",    "finish_amount": 37,    "mch_id": "csBbLaXHKixsPoBDgUcoybOqJ",    "sub_mch_id": "IJVsOMaULVxKJUpBiyJggdrOU",    "appid": "GkwGbQlCqDhQJffVDujkFydvx",    "update_time": "2232-05-10T13:24:13.148894895+08:00"}



*/

// Profitshare struct is a row record of the profitshare table in the wxpay database
type Profitshare struct {
	//[ 0] id                                             INT8                 null: false  primary: true   isArray: false  auto: false  col: INT8            len: -1      default: []
	ID int64 `gorm:"primary_key;column:id;type:INT8;"`
	//[ 1] brand_id                                       VARCHAR(16)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 16      default: []
	BrandID string `gorm:"column:brand_id;type:VARCHAR;size:16;"`
	//[ 2] mch_id                                         VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
	MchID string `gorm:"column:mch_id;type:VARCHAR;size:32;"`
	//[ 3] sub_mch_id                                     VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
	SubMchID string `gorm:"column:sub_mch_id;type:VARCHAR;size:32;"`
	//[ 4] appid                                          VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
	AppID string `gorm:"column:appid;type:VARCHAR;size:32;"`
	//[ 5] wx_trans_id                                    VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
	WxTransID string `gorm:"column:wx_trans_id;type:VARCHAR;size:32;"`
	//[ 6] out_trade_no                                   VARCHAR(64)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 64      default: []
	OutTradeNo string `gorm:"column:out_trade_no;type:VARCHAR;size:32;"`
	//[ 6] out_order_no                                   VARCHAR(64)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 64      default: []
	OutOrderNo string `gorm:"column:out_order_no;type:VARCHAR;size:64;"`
	//[ 7] receivers                                      JSONB                null: false  primary: false  isArray: false  auto: false  col: JSONB           len: -1      default: []
	Receivers datatypes.JSON `gorm:"column:receivers;type:JSONB;"`
	//[ 8] status                                         VARCHAR(255)         null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 255     default: []
	Status sql.NullString `gorm:"column:status;type:VARCHAR;size:255;"`
	//[ 9] wx_order_id                                    VARCHAR(64)          null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 64      default: []
	WxOrderID sql.NullString `gorm:"column:wx_order_id;type:VARCHAR;size:64;"`
	//[10] close_reason                                   VARCHAR(255)         null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 255     default: []
	CloseReason sql.NullString `gorm:"column:close_reason;type:VARCHAR;size:255;"`
	//[11] finish_amount                                  INT8                 null: true   primary: false  isArray: false  auto: false  col: INT8            len: -1      default: []
	FinishAmount sql.NullInt64 `gorm:"column:finish_amount;type:INT8;"`
	//[12] finish_description                             VARCHAR(80)          null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 80      default: []
	FinishDescription sql.NullString `gorm:"column:finish_description;type:VARCHAR;size:80;"`
	//[13] extra                                          JSONB                null: true   primary: false  isArray: false  auto: false  col: JSONB           len: -1      default: []
	Extra datatypes.JSON `gorm:"column:extra;type:JSONB;"`
	//[14] create_time                                    TIMESTAMPTZ          null: false  primary: false  isArray: false  auto: false  col: TIMESTAMPTZ     len: -1      default: []
	CreateTime time.Time `gorm:"column:create_time;type:TIMESTAMPTZ;"`
	//[15] update_time                                    TIMESTAMPTZ          null: false  primary: false  isArray: false  auto: false  col: TIMESTAMPTZ     len: -1      default: []
	UpdateTime time.Time `gorm:"column:update_time;type:TIMESTAMPTZ;"`
}

// TableName sets the insert table name for this struct type
func (p *Profitshare) TableName() string {
	return "profitshare"
}

// 处理中
const ProfitOrderStatusProcessing = "PROCESSING"

// 分账完成
const ProfitOrderStatusFinished = "FINISHED"

// 分账失败，已关闭
const ProfitOrderStatusClosed = "CLOSED"

type Receiver struct {
	// 分账接收方类型
	Type string
	// 分账接收方帐号
	Account string
	// 分账动账金额
	Amount int64
	// 分账/回退描述
	Description string
	// 分账接受方姓名
	ReceiverName string
}

type Receivers []Receiver

func (info *Receivers) ToJson() (r datatypes.JSON) {
	r, _ = json.Marshal(info)
	return
}

func (info *Receivers) ToStruct(r datatypes.JSON) {
	b, _ := r.MarshalJSON()
	_ = json.Unmarshal(b, info)
}

func (p *Profitshare) GetReceivers() (r Receivers) {
	r = Receivers{}
	r.ToStruct(p.Receivers)
	return
}

// 检查品牌归属
func (p *Profitshare) DoesBelongTo(brandID string) (belong bool) {
	return brandID == p.BrandID
}

// 检查分账单状态是否终态
func (p *Profitshare) IsFinalState() bool {
	switch util.ConvertNullString(p.Status) {
	case ProfitOrderStatusFinished, ProfitOrderStatusClosed:
		return true
	default:
		return false
	}
}

// 检查分账单状态是否处理中
func (p *Profitshare) IsProcessing() bool {
	return util.ConvertNullString(p.Status) == ProfitOrderStatusProcessing
}

// 是否分账完结订单
func (p *Profitshare) IsFinishOrder() bool {
	return p.FinishDescription.Valid
}

// 分账成功
func (p *Profitshare) Success(finishAmount int64) {
	p.Status = util.AdaptNullString(ProfitOrderStatusFinished)
	p.UpdateTime = util.GetNow()
	if p.IsFinishOrder() {
		// 分账完结订单
		p.FinishAmount = sql.NullInt64{
			Int64: finishAmount,
			Valid: true,
		}
	}
}

// 分账失败
func (p *Profitshare) Failed(reason string) {
	p.Status = util.AdaptNullString(ProfitOrderStatusClosed)
	p.CloseReason = util.AdaptNullString(reason)
	p.UpdateTime = util.GetNow()
}

// 分账过程中
func (p *Profitshare) Processing() {
	p.Status = util.AdaptNullString(ProfitOrderStatusProcessing)
	p.UpdateTime = util.GetNow()
}
